home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / egxshow.arc / SHOWEGA.C < prev    next >
Text File  |  1991-09-17  |  17KB  |  679 lines

  1. /* written in MIX power C version 2.0   */
  2. /* an EGA file viewer                   */
  3.  
  4. /* I originally developed this template as a CGA file viewer...  */
  5. /* hopefully I have removed anything from that application which */
  6. /* may appear confusing...  */
  7.  
  8. /* writing direct to screen */
  9. /* using bios calls to set the adapter */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <dos.h>
  14. #include <bios.h>
  15. #include <conio.h>
  16. #include <direct.h>
  17. #include <malloc.h>
  18. #include <fcntl.h>
  19. #include <io.h>
  20. #include <stdlib.h>
  21.  
  22. /* a group of handy definitions */
  23.  
  24. #define BLACK   0
  25. #define BLUE    1
  26. #define GREEN   2
  27. #define CYAN    3
  28. #define RED     4
  29. #define MAGENTA 5
  30. #define BROWN   6
  31. #define WHITE   7
  32. #define GRAY      8
  33. #define LBLUE     9
  34. #define LGREEN    10
  35. #define LCYAN     11
  36. #define LRED      12
  37. #define LMAGENTA  13
  38. #define YELLOW    14
  39. #define BWHITE    15
  40.  
  41. #define ESCAPE  '\x1b'
  42. #define TEXT     3
  43. #define CGA_320  4
  44. #define HERCULES 99
  45.  
  46. int ADAPTER = CGA_320;
  47. int screen_mode = CGA_320;
  48.  
  49. #define BLANK     32
  50. #define FAT       219
  51.  
  52.  
  53. #define ENTERKEY   '\x0d' /* character generated by the Enter Key          */
  54. #define ESCKEY     '\x1b' /* character generated by the Esc key            */
  55. #define FUNCKEY    '\x00' /* first character generated by function keys    */
  56. #define UPARROW    'H'    /* second character generated by up-arrow key    */
  57. #define DOWNARROW  'P'    /* second character generated by down-arrow key  */
  58. #define LTARROW    'K'    /* second character generated by left-arrow key  */
  59. #define RTARROW    'M'    /* second character generated by right-arrow key */
  60. #define PGUP       'I'    /* second character generated by page up key     */
  61. #define PGDOWN     'Q'    /* second character generated by page down key   */
  62.  
  63. /* starting at character 59*/
  64. #define F1         ';'    /* second character generated by numerical fkeys */
  65. #define F2         '<'
  66. #define F3         '='
  67. #define F4         '>'
  68. #define F5         '?'
  69. #define F6         '@'
  70. #define F7         'A'
  71. #define F8         'B'
  72. #define F9         'C'
  73. #define F10        'D'
  74. /* ending at character 68  */
  75.  
  76. #define CRETURN '\x0d'
  77. #define LFEED   '\x0A'
  78. #define CTRLZ   '\x1a'
  79. #define DELETE  '\x7f'
  80.  
  81. #define SINGLE    218
  82. #define DOUBLE    201
  83.  
  84. char wildfiles[200][15];
  85.  
  86. int filecords[84][2]=
  87. {
  88.     2,  4,  2,  23,  2, 42,  2, 61,
  89.     3,  4,  3,  23,  3, 42,  3, 61,
  90.     4,  4,  4,  23,  4, 42,  4, 61,
  91.     5,  4,  5,  23,  5, 42,  5, 61,
  92.     6,  4,  6,  23,  6, 42,  6, 61,
  93.     7,  4,  7,  23,  7, 42,  7, 61,
  94.     8,  4,  8,  23,  8, 42,  8, 61,
  95.     9,  4,  9,  23,  9, 42,  9, 61,
  96.     10, 4, 10,  23, 10, 42, 10, 61,
  97.     11, 4, 11,  23, 11, 42, 11, 61,
  98.     12, 4, 12,  23, 12, 42, 12, 61,
  99.     13, 4, 13,  23, 13, 42, 13, 61,
  100.     14, 4, 14,  23, 14, 42, 14, 61,
  101.     15, 4, 15,  23, 15, 42, 15, 61,
  102.     16, 4, 16,  23, 16, 42, 16, 61,
  103.     17, 4, 17,  23, 17, 42, 17, 61,
  104.     18, 4, 18,  23, 18, 42, 18, 61,
  105.     19, 4, 19,  23, 19, 42, 19, 61,
  106.     20, 4, 20,  23, 20, 42, 20, 61,
  107.     21, 4, 21,  23, 21, 42, 21, 61,
  108.     22, 4, 22,  23, 22, 42, 22, 61};
  109.  
  110. int getfiles(char *filetype)
  111. {
  112.  
  113.     char buffer[15];
  114.     int wildcounter=0;
  115.  
  116.     struct ffblk wild_card;
  117.  
  118.     memset(wildfiles,0,sizeof(wildfiles));
  119.     sprintf(buffer,"*.%s",filetype);
  120.  
  121.     if(findfirst(buffer,&wild_card,FA_NORMAL)==0)
  122.     {
  123.         strcpy(wildfiles[wildcounter],wild_card.ff_name);
  124.         wildcounter++;
  125.  
  126.     while(findnext(&wild_card)==0){
  127.            strcpy(wildfiles[wildcounter],wild_card.ff_name);
  128.            wildcounter++;
  129.            }
  130.            }
  131.  
  132.  
  133.     if(wildcounter>1)qsort(wildfiles,wildcounter,15,strcmp);
  134. return wildcounter;
  135. }
  136.  
  137. #define EGA '\x10'
  138.  
  139. unsigned char setcrtmode(unsigned char vidmode)
  140. {
  141.     union REGS inregs, outregs;
  142.  
  143.     /* set mode */
  144.     inregs.h.ah = 0;
  145.     inregs.h.al = vidmode;
  146.     int86( 0x10, &inregs, &outregs );
  147.  
  148.     /* get mode */
  149.     inregs.h.ah = 0xf;
  150.     int86( 0x10, &inregs, &outregs );
  151.  
  152.     /* return mode */
  153.     return outregs.h.al;
  154.  
  155. }
  156.  
  157.  
  158.  
  159. /* the structure of an ega color number...
  160.  
  161.   | 5 | 4 | 3 | 2 | 1 | 0 |
  162.   |   |   |   |   |   |   |
  163.   | R | G | B | R | G | B |  color triples (rgb gun values)
  164.               |
  165.     high      | low
  166.     intensity   intensity
  167.  
  168. */
  169.  
  170. /* byte 0-15 are colors... byte 16 is overscan register  */
  171. unsigned char egainfo[17];      /* the values to be used */
  172. void palettebits(int i, unsigned char color,
  173.                  unsigned char arg1, unsigned char arg2)
  174. {
  175.  
  176.     if(color>0x33)egainfo[i]|=arg1;
  177.  
  178.     if(color>0x77)
  179.         {
  180.             egainfo[i]&=~arg1;
  181.             egainfo[i]|= arg2;
  182.         }
  183.  
  184.      if(color>0xbb)egainfo[i]|=(arg1+arg2);
  185.  
  186.  
  187. }
  188.  
  189.  
  190. void rgb2ega(unsigned char *ptr)
  191. {
  192.     int i;
  193.     unsigned char color;
  194.  
  195.  
  196.     for(i=0;i<16;i++)
  197.     {
  198.         egainfo[i]=0;
  199.         color=*ptr++;
  200.         palettebits(i,color,0x20,0x04);
  201.         color=*ptr++;
  202.         palettebits(i,color,0x10,0x02);
  203.         color=*ptr++;
  204.         palettebits(i,color,0x08,0x01);
  205.      }
  206.      egainfo[0]=0;
  207.  
  208. }
  209.  
  210. int setegapalette()
  211. {
  212.     union REGS regs;
  213.     unsigned char i;
  214.  
  215.     for(i=0;i<16;i++)
  216.     {
  217.         regs.h.ah  = 0x10;  /* function 10h */
  218.         regs.h.al  = 0x00;
  219.         regs.h.bh  = egainfo[i];
  220.         regs.h.bl  = i;
  221.         int86(0x10,®s,®s);
  222.         }
  223.  
  224.         /* dump data to color registers */
  225.  
  226. return 0;
  227.  
  228. }
  229.  
  230.  
  231. /* type conversion function */
  232. unsigned int byteword(unsigned char a, unsigned char b){return b<<8|a;}
  233. int checkforpcx(unsigned char *pcxheader)
  234. {
  235.     unsigned int zsoft,codetype,pixbits;
  236.     unsigned int xmin, ymin, xmax, ymax;
  237.     unsigned int no_planes, bytesperline;
  238.     int invalid = -1, valid = 0, status=valid;
  239.  
  240.     /* read the file header */
  241.  
  242.     zsoft   =pcxheader[0];
  243.     codetype=pcxheader[2];
  244.     pixbits =pcxheader[3];
  245.  
  246.     if(zsoft!=10)        status = invalid;
  247.     if(codetype!=1)      status = invalid;
  248.     if(pixbits !=1)      status = invalid;
  249.  
  250.     xmin=byteword(pcxheader[4],pcxheader[5]);
  251.     ymin=byteword(pcxheader[6],pcxheader[7]);
  252.     xmax=byteword(pcxheader[8],pcxheader[9]);
  253.     ymax=byteword(pcxheader[10],pcxheader[11]);
  254.     no_planes   =pcxheader[65];
  255.     bytesperline=byteword(pcxheader[66],pcxheader[67]);
  256.  
  257.  
  258.       if(xmin != 0  )       status = invalid;
  259.       if(ymin != 0  )       status = invalid;
  260.       if(xmax != 639)       status = invalid;
  261.       if(ymax != 349)       status = invalid;
  262.       if(no_planes!=4)      status = invalid;
  263.       if(bytesperline !=80)status = invalid;
  264.       return status;
  265.  
  266. }
  267.  
  268. char indexmap[]={ 1,2,4,8};
  269. void index_set(indexval)
  270.     {
  271.         outp(0x3c4,2);
  272.         outp(0x3c5,indexmap[indexval]);
  273.         }
  274.  
  275. int pcxega(char *name)
  276. {
  277.  
  278.     unsigned long ctr=0;
  279.     unsigned long byteoff=0;
  280.     unsigned int packet;
  281.     unsigned char byte,bytecount;
  282.     unsigned char *ptr;
  283.     unsigned int temp;
  284.     int safety=0;
  285.  
  286.  
  287.     FILE *fp;
  288.     unsigned char pcxheader[128];
  289.  
  290.     if((fp = fopen(name,"rb"))==NULL)return -1;
  291.  
  292.     fread(pcxheader,128,1,fp);
  293.     if(checkforpcx(pcxheader)!=0)
  294.         {
  295.           fclose(fp);
  296.           return -1;
  297.           }        
  298.  
  299.      ptr=(char *)&pcxheader[16];
  300.      rgb2ega(ptr);
  301.      setegapalette();
  302.  
  303.      temp=0;
  304.      index_set(0);
  305.  
  306.     do{ bytecount=1;                          /* start with a seed count */
  307.         byte=fgetc(fp);
  308.                                               /* check to see if its raw */
  309.         if(0xC0 == (0xC0 &byte)){             /* if its not, run encoded */
  310.                     bytecount= 0x3f &byte;
  311.                     byte=fgetc(fp);
  312.                     }
  313.  
  314.         switch(temp)
  315.         {
  316.          case 320:  temp=0;
  317.          case 0  :  ptr=(char *)0xa0000000l+ctr;
  318.                     index_set(0);
  319.                     safety=0;
  320.                     break;
  321.          case 80 :  ptr=(char *)0xa0000000l+ctr;
  322.                     index_set(1);
  323.                     safety=0;
  324.                     break;
  325.          case 160:  ptr=(char *)0xa0000000l+ctr;
  326.                     index_set(2);
  327.                     safety=0;
  328.                     break;
  329.          case 240:  ptr=(char *)0xa0000000l+ctr;
  330.                     ctr+=80;
  331.                     safety=0;
  332.                     index_set(3);
  333.                     break;
  334.         }
  335.         for(packet=0;packet<bytecount;packet++){
  336.                      *ptr++=byte;
  337.                      byteoff++;
  338.                      safety++;
  339.                      temp++;
  340.                      if(safety>79)packet=bytecount;
  341.                      }
  342.         }while(byteoff<112000l);
  343.  
  344.     fclose(fp);
  345.     return 0;
  346. }
  347.  
  348.  
  349. void cursoroff(void)
  350. {
  351.    union REGS regs;
  352.  
  353.    regs.h.ah = 0x01;
  354.    regs.x.cx = 0x2000;
  355.    int86(0x10,®s,®s);
  356. }
  357.  
  358.  
  359. void cursoron(void)
  360. {
  361.    union REGS regs;
  362.  
  363.    regs.h.ah = 0x01;
  364.    regs.x.cx = 0x0607;
  365.    int86(0x10,®s,®s);
  366. }
  367.  
  368.  
  369. void cls(int BACK,int FRONT)
  370. {
  371.     union REGS reg;
  372.  
  373.     reg.h.ah = 6;
  374.     reg.h.al = 0;
  375.     reg.h.ch = 0;
  376.     reg.h.cl = 0;
  377.     reg.h.dh = 24;
  378.     reg.h.dl = 79;
  379.     reg.h.bh = (BACK << 4) + FRONT;
  380.     int86(0x10, ®, ®);
  381. }
  382.  
  383.  
  384.  
  385. void DMC(int Row, int Column, unsigned BYTE, int BACK, int FRONT, int QUANT)
  386. {
  387.     /*  DMA replacement for writechs function */
  388.  
  389.     unsigned segment= 0xB000, offset;
  390.     int One_Too_Many = (QUANT+1);
  391.     int i, Attribute;
  392.  
  393.     Attribute = (BACK << 4) + FRONT;
  394.  
  395.     if(ADAPTER!=HERCULES)segment = 0xB800;    /* CGA or Equivalent */
  396.     offset = 160 * Row + 2 * Column ;
  397.     for (i=1; i< One_Too_Many ; i++){
  398.         poke(segment,offset, BYTE|Attribute<<8);
  399.         offset+=2;
  400.         }
  401. }
  402.  
  403.  
  404. void DMM(char *String, int Row, int Column, int BACK, int FRONT)
  405. {
  406.     /*  DMA replacement for puts
  407.         centre justified string    */
  408.  
  409.     unsigned Character, segment=0xB000, offset;
  410.     int Attribute;
  411.  
  412.     Attribute = (BACK << 4) + FRONT;
  413.  
  414.     Column =   ((Column+1)-(.5*(strlen(String))));
  415.  
  416.     if(ADAPTER != HERCULES)segment = 0xB800;    /* CGA or Equivalent */
  417.     offset = 160 * Row + 2 * Column ;
  418.     while ((Character = *String++)!=0){
  419.         if(Character!='\n'){
  420.         poke(segment,offset,Character|Attribute<<8);
  421.         offset+=2;
  422.         }
  423.         }
  424. }
  425.  
  426.  
  427. void DML(char *String, int Row, int Column, int BACK, int FRONT)
  428. {
  429.     /*  DMA replacement for puts
  430.         left justified string    */
  431.     unsigned Character, segment=0xB000, offset;
  432.     int Attribute;
  433.  
  434.     Attribute = (BACK << 4) + FRONT;
  435.  
  436.     if(ADAPTER!=HERCULES)segment = 0xB800; /* CGA or Equivalent */
  437.     offset = 160 * Row + 2 * Column ;
  438.     while ((Character = *String++)!=0){
  439.         if(Character!='\n'){
  440.         poke(segment,offset, Character|Attribute<<8);
  441.         offset +=2;
  442.         }
  443.     }
  444. }
  445.  
  446.  
  447. void PAINT(int *cor,int fore, int bk,unsigned char Character)
  448. {
  449.    int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
  450.    int index,linelength = ((bcol+1) - (tcol));
  451.    for (index = (trow); index < brow+1; index++)
  452.    DMC(index,tcol,Character,bk,fore,linelength);
  453. }
  454.  
  455. void BORDERBOX(int *cor,int fore, int bk,unsigned char BRDR)
  456. {
  457.  
  458. int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
  459.     /* draws an outline only using a specified border character */
  460. int index;
  461. int homerow = (brow-1);
  462. int homecol = (tcol+1);
  463. int linelength = ((bcol) - (tcol+1));
  464.  
  465. int TLcorner,TRcorner,BLcorner,BRcorner,HORT,VERT;
  466.  
  467.           switch(BRDR){
  468.                case DOUBLE: {
  469.                             TLcorner = 201;
  470.                             TRcorner = 187;
  471.                             BLcorner = 200;
  472.                             BRcorner = 188;
  473.                             HORT = 205;
  474.                             VERT = 186;
  475.                             break;
  476.                         }
  477.                case SINGLE: {
  478.                             TLcorner = 218;
  479.                             TRcorner = 191;
  480.                             BLcorner = 192;
  481.                             BRcorner = 217;
  482.                             HORT = 196;
  483.                             VERT = 179;
  484.                             break;
  485.                         }
  486.                default:    {
  487.                             TLcorner = BRDR;
  488.                             TRcorner = BRDR;
  489.                             BLcorner = BRDR;
  490.                             BRcorner = BRDR;
  491.                             HORT = BRDR;
  492.                             VERT = BRDR;
  493.                         }
  494.             }
  495.    DMC(trow,tcol,TLcorner,bk,fore,1);         /* top */
  496.    DMC(trow,homecol,HORT,bk,fore,linelength);
  497.    DMC(trow,bcol,TRcorner,bk,fore,1);
  498.    for (index = (trow+1); index < brow; index++){
  499.        DMC(index,tcol,VERT,bk,fore,1);
  500.        DMC(index,bcol,VERT,bk,fore,1);
  501.        }
  502.    DMC(brow,tcol,BLcorner,bk,fore,1);
  503.    DMC(brow,homecol,HORT,bk,fore,linelength);
  504.    DMC(brow,bcol,BRcorner,bk,fore,1);        /* bottom */
  505. }
  506.  
  507.  
  508.  
  509. unsigned char far *crt    =(unsigned char *) 0xB8000000l;
  510.  
  511. void getadaptertype(void)
  512. {
  513.     if(((biosequip() >>4) &3) <3)ADAPTER=CGA_320;
  514.     else
  515.     {
  516.         ADAPTER=HERCULES;
  517.         crt = (unsigned char far *)0xb0000000l;
  518.     }
  519. }
  520.  
  521.  
  522. unsigned char far *textscreen;
  523. void initgraphbuffers()
  524. {
  525.     textscreen   = _fmalloc(4000);
  526. }
  527.  
  528. void freegraphbuffers()
  529. {
  530.     _ffree(textscreen);
  531.  
  532. }
  533.  
  534. void bronx(void)
  535. {
  536. sound(60,4);
  537. sound(40,8);
  538. }
  539.  
  540.  
  541. /* THE LOADER */
  542. int vux(char *picfile)
  543. {
  544.    int status = 0;
  545.    char c;
  546.    char buffer[66],buffer2[66];
  547.    char *wordptr;
  548.  
  549.    strcpy(buffer,picfile);
  550.  
  551.  
  552.    memcpy(textscreen,crt,4000);
  553.    if((setcrtmode(EGA))!=EGA)
  554.    {
  555.     cls(BLACK,WHITE);
  556.     bronx();
  557.     puts("EGA adapter required...press any key");
  558.     }
  559.    else
  560.    {
  561.        wordptr=strtok(buffer,".  \n");
  562.        sprintf(buffer2,"%s.PCX",buffer);
  563.        status =pcxega(buffer2);
  564.    }
  565.    if(!status)while((c=getch())!=27);
  566.    else bronx();
  567.  
  568.    setcrtmode(TEXT);
  569.    cursoroff();
  570.    memcpy(crt,textscreen,4000);
  571.    return 0;
  572.  
  573. }
  574.  
  575. int displayfiles(char *filetype)
  576. {
  577.    int i;
  578.    int hotfile= 0;
  579.    int coldfile=0;
  580.    int filecount = getfiles(filetype);
  581.    char c;
  582.    int background = BLUE, foreground = LCYAN;
  583.    int cor[4];
  584.  
  585.    int breverse=BLACK,freverse=BWHITE;
  586.    if(ADAPTER==HERCULES){
  587.                          breverse=WHITE;
  588.                          freverse=BLACK;
  589.                          }
  590.  
  591.    if(filecount==0)return 0;
  592.    cls(background, foreground);
  593.    cursoroff();
  594.  
  595.    cor[0]=0;
  596.    cor[1]=0;
  597.    cor[2]=24;
  598.    cor[3]=79;
  599.  
  600.    BORDERBOX(cor,foreground,background,DOUBLE);
  601.    DMC(0,1,1,background,foreground,78);
  602.    DMM(
  603.    " SHOWEGA(C) Copyright 1991 by Bill Buckels * EGA .PCX file Viewer ",
  604.    0,39,background,foreground);
  605.  DMM(
  606.  
  607. " Use Arrow Keys To Select * Press Enter To View | Press ESCape to Exit ",
  608.         24,39,background,foreground);
  609.  
  610.  
  611.    if(filecount>84)filecount=84;
  612.  
  613.  
  614.    for(i=0;i<filecount;i++)
  615.        DML(wildfiles[i],filecords[i][0],filecords[i][1],
  616.        background,foreground);
  617.        DML(wildfiles[hotfile],filecords[hotfile][0],filecords[hotfile][1],
  618.        breverse,freverse);
  619.  
  620.    while((c=getch())!=ESCKEY)
  621.     {   if(c==ENTERKEY)vux(wildfiles[hotfile]);
  622.         if(c==FUNCKEY)
  623.         {
  624.             c=getch();
  625.             switch(c)
  626.             {
  627.               case UPARROW  : if(hotfile<4)break;
  628.                               hotfile-=4;
  629.                               break;
  630.  
  631.               case DOWNARROW: if(hotfile>(filecount-5))break;
  632.                               hotfile+=4;
  633.                               break;
  634.  
  635.               case RTARROW  :
  636.                               if(hotfile<(filecount-1))
  637.                               hotfile++;
  638.                               break;
  639.  
  640.               case LTARROW  : if(hotfile==0)break;
  641.                               hotfile--;
  642.                               break;
  643.               case PGUP     :
  644.               case PGDOWN   : break;
  645.               }
  646.             }
  647.               if(hotfile!=coldfile)
  648.               {
  649.                 DML(wildfiles[coldfile],
  650.                     filecords[coldfile][0],filecords[coldfile][1],
  651.                     background,foreground);
  652.                 DML(wildfiles[hotfile],
  653.                     filecords[hotfile][0],filecords[hotfile][1],
  654.                     breverse,freverse);
  655.                     coldfile=hotfile;
  656.                     }
  657.                 }
  658.  
  659.    cursoron();
  660.    cls(BLACK,WHITE);
  661.    return 0;
  662.  
  663. }
  664.  
  665.  
  666. main(int argc, char **argv)
  667. {
  668.     getadaptertype();
  669.     initgraphbuffers();
  670.     displayfiles("PCX");
  671.     freegraphbuffers();
  672.     exit(0);
  673.  
  674. }
  675.  
  676.  
  677.  
  678.  
  679.